# 多周期
# 买入条件：日MACD金叉、周RSI小于50
# 卖出条件：价格较最高收盘价回撤5%卖出
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import backtrader as bt
import backtrader.feeds as btfeeds
import backtrader.indicators as btind
import datetime
import pandas as pd
from collections import defaultdict

class RSIMACDMultiTF(bt.Strategy):
    params = (
        ('trailamount', 0.5),
        ('trailpercent', 1),

    )

    def __init__(self):
        # 存储不同数据的技术指标
        self.inds = dict()
        # 存储特定股票的订单，key为股票的代码
        self.orders = dict()
        # 遍历所有数据
        #for d in self.datas:
        for i, d in enumerate(self.datas):
            #i=len(self.datas)
            self.orders[d._name] = None
            # 为每个数据定义字典，存储技术指标
            self.inds[d] = dict()
            # 判断d是否为日线数据
            if 0 == i % 2:
                self.inds[d]['crossup'] = btind.CrossUp(btind.MACD(d).macd, btind.MACD(d).signal)
            # d为周线数据
            else:
                self.inds[d]['rsi'] = btind.RSI_Safe(d)
                #print('111111')
                #break;
                #self.inds[d]['rsi'] = .btindRelativeStrengthIndex(d)
                #.RelativeStrengthIndex()RSI_Safe(d)

    def next(self):
        #print(self.datetime.date())
        for i, d in enumerate(self.datas):
            # 如果处理周线数据则跳过买卖条件，因为已在日线数据判断处理过
            if 1 == i % 2:
                continue
            pos = self.getposition(d)
            # 不在场内，则可以买入
            if not len(pos):
                # 达到买入条件
                if self.inds[d]['crossup'][0] and self.inds[self.datas[i + 1]]['rsi'][0] <50 and self.inds[self.datas[i + 1]]['rsi'][0] >35:
                    print(d.datetime.date(0),self.datas[i + 1].datetime.date(0))
                    # 买入手数，如果是多只股票回测，这里需要修改
                    stake = int(self.broker.cash // (d.close[0] * 100)) * 100
                    # 买买买
                    self.buy(data = d, size = stake)
            elif not self.orders[d._name]:
                # 下保护点卖单
                self.orders[d._name] = self.close(data = d, exectype= bt.Order.StopTrail,
                            trailamount=self.p.trailamount,
                            trailpercent=self.p.trailpercent)

    def notify_order(self, order):

        if order.status in [order.Submitted, order.Accepted]:
            # 如订单已被处理，则不用做任何事情
            return
        if order.status in [order.Completed]:
            if order.isbuy():
                print('{} BUY {} EXECUTED, Price: {:.2f}'.format(self.datetime.date(), order.data._name,
                                                                 order.executed.price))
            else:  # Sell
                self.orders[order.data._name] = None
                print('{} SELL {} EXECUTED, Price: {:.2f}'.format(self.datetime.date(), order.data._name,
                                                                  order.executed.price))
        """
        订单状态处理

        Arguments:
            order {object} -- 订单状态
        """



        # 订单状态处理完成，设为空
        self.order = None

    def notify_trade(self, trade):



        """
        交易成果

        Arguments:
            trade {object} -- 交易状态
        """
        if not trade.isclosed:
            return

        # 显示交易的毛利率和净利润
        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                 (trade.pnl, trade.pnlcomm), doprint=True)


    def log(self, txt, dt=None,doprint=False):
        if False or doprint:
            dt = dt or self.datas[0].datetime.date(0)
            print(f'{dt.isoformat()},{txt}')
